const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
const name = 'label-platform'
const version = 1

function IndexedDB(Vue) {
  var database

  Vue.prototype.$initIndexedDB = function (callback, tableName = 'pcd_blobs', keyPath = 'file_name') {
    if (database) {
      callback(database)
    } else {
      const request = indexedDB.open(name, version)
      request.onupgradeneeded = function (event) {
        database = event.target.result
        if (database.objectStoreNames.contains(tableName)) {
          database.deleteObjectStore(tableName)
        }
        database.createObjectStore(tableName, { keyPath: keyPath })
      }

      request.onsuccess = function (event) {
        database = event.target.result
        callback(database)
      }

      request.onerror = function (event) {
        console.warn('Failed to open: ', event)
      }
    }
  }

  Vue.prototype.$getAllKeys = function (callback, tableName = 'pcd_blobs') {
    if (database === undefined) return

    const transaction = database.transaction([tableName], 'readwrite')
    const objectStore = transaction.objectStore(tableName)
    const req = objectStore.getAllKeys()
    req.onsuccess = function () {
      callback(req.result)
    }

    req.onerror = function () {
      callback(null)
    }
  }

  Vue.prototype.$get = function (fileName, callback, errorCallBack, tableName = 'pcd_blobs') {
    if (database === undefined) return

    const transaction = database.transaction([tableName], 'readwrite')
    const objectStore = transaction.objectStore(tableName)

    const request = objectStore.get(fileName)
    request.onsuccess = function (event) {
      if (event.target.result) {
        console.debug('fileBlob: ' + fileName + ' found')
        callback(event.target.result)
      } else if (errorCallBack) {
        errorCallBack()
      }
    }

    request.onerror = function (event) {
      console.info('fileBlob: ' + fileName + ' not found', event)
      if (errorCallBack) errorCallBack()
    }
  }

  // Vue.prototype.$delete = function ( fileName, callback, errorCallBack, tableName = "pcd_blobs" ) {

  //     if ( !database ) return;

  //     if(database.objectStoreNames.contains(fileName)) {
  //         database.deleteObjectStore("");
  //     }

  //     // const transaction = database.transaction( [ tableName ], 'readwrite' );
  //     // const objectStore = transaction.objectStore( tableName );

  //     // const request = objectStore.delete( fileName );
  //     // request.onsuccess = function ( event ) {
  //     //     if(event.target.result) {
  //     //         console.debug("fileBlob: " + fileName + " deleted.");
  //     //         if(callback) {
  //     //             callback(event.target.result);
  //     //         }
  //     //     }
  //     //     else if(errorCallBack) {
  //     //         errorCallBack();
  //     //     }
  //     // };

  //     // request.onerror = function (event) {
  //     //     console.info("fileBlob: " + fileName + " not found", event);
  //     //     if(errorCallBack) errorCallBack();
  //     // }
  // }

  Vue.prototype.$save = function (data, tableName = 'pcd_blobs') {
    if (database === undefined) return

    const transaction = database.transaction([tableName], 'readwrite')
    const objectStore = transaction.objectStore(tableName)

    const request = objectStore.get(data.file_name)
    request.onsuccess = function (event) {
      if (event.target.result) {
        console.info('fileBlob: ' + data.file_name + ' exist.')
      } else {
        saveData(data)
      }
    }

    request.onerror = function (event) {
      saveData(data)
    }
  }

  function saveData(data, tableName = 'pcd_blobs') {
    const start = performance.now()

    const transaction = database.transaction([tableName], 'readwrite')
    const objectStore = transaction.objectStore(tableName)

    var countRequest = objectStore.count()
    countRequest.onsuccess = function () {
      if (countRequest.result > 800) {
        console.log('Removed old cached files.')
        objectStore.clear()
      }

      const request = objectStore.put(data)
      request.onsuccess = function () {
        console.info(
          '[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']',
          'Saved state to IndexedDB. ' + (performance.now() - start).toFixed(2) + 'ms'
        )
      }

      request.onerror = function (event) {
        console.warn('save error', event)
        objectStore.clear()
      }
    }
  }

  Vue.prototype.$clearIndexedDB = function (tableName = 'pcd_blobs') {
    try {
      if (database === undefined) return

      var transaction = database.transaction([tableName], 'readwrite')
      var objectStore = transaction.objectStore(tableName)
      if (objectStore) {
        var request = objectStore.clear()
        request.onsuccess = function () {
          console.info('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Cleared IndexedDB.')
        }

        request.onerror = function (event) {
          console.warn('clear error', event)
        }
      }
    } catch (e) {
      console.warn('clearIndexedDB Exception:', e)
    }
  }

  var functions = ['$initIndexedDB', '$get', '$save', '$clearIndexedDB']

  Vue.indexedDB = {}
  functions.forEach(function (name) {
    Vue.indexedDB[name] = Vue.prototype[name]
  })

  Vue.prototype.$initIndexedDB((db) => {
    console.debug('indexedDB initialized', db.name, db.version)
  })
}

IndexedDB.version = '0.0.1'

export default IndexedDB
